package com.zycfc.zsf.boot.util.ead;

import java.nio.charset.*;
import java.security.*;
import java.io.*;

public class EadMD5Utils
{
    public static final String KEY_SHA1 = "SHA-1";
    public static final String KEY_MD5 = "MD5";
    
    public static String encrypt(final String txt, final String salt) throws Exception {
        return Hex.encodeHexStr(digest(txt.getBytes(StandardCharsets.UTF_8), "MD5", salt.getBytes(StandardCharsets.UTF_8), 1));
    }
    
    public static String encrypt(final String txt) throws Exception {
        return Hex.encodeHexStr(digest(txt.getBytes(StandardCharsets.UTF_8), "MD5", null, 1));
    }
    
    private static byte[] digest(final byte[] input, final String algorithm, final byte[] salt, final int iterations) {
        try {
            final MessageDigest digest = MessageDigest.getInstance(algorithm);
            if (salt != null) {
                digest.update(salt);
            }
            byte[] result = digest.digest(input);
            for (int i = 1; i < iterations; ++i) {
                digest.reset();
                result = digest.digest(result);
            }
            return result;
        }
        catch (GeneralSecurityException e) {
            e.printStackTrace();
            throw unchecked(e);
        }
    }
    
    public static byte[] encryptFile(final InputStream input) throws IOException {
        return digest(input, "MD5");
    }
    
    private static byte[] digest(final InputStream input, final String algorithm) throws IOException {
        try {
            final MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
            final int bufferLength = 8192;
            final byte[] buffer = new byte[bufferLength];
            for (int read = input.read(buffer, 0, bufferLength); read > -1; read = input.read(buffer, 0, bufferLength)) {
                messageDigest.update(buffer, 0, read);
            }
            return messageDigest.digest();
        }
        catch (GeneralSecurityException e) {
            throw unchecked(e);
        }
    }
    
    public static RuntimeException unchecked(final Throwable ex) {
        if (ex instanceof RuntimeException) {
            return (RuntimeException)ex;
        }
        return new RuntimeException(ex);
    }
}
